package cn.mw.cmdb.template.strategy.handler;

import cn.mw.cmdb.exception.ZabbixResultException;
import cn.mw.cmdb.template.constant.MwTemplateConfigurationConstant;
import cn.mw.cmdb.template.entity.ApplicationDto;
import cn.mw.cmdb.template.entity.convert.*;
import cn.mw.cmdb.template.enums.TemplateDetailEnum;
import cn.mw.cmdb.template.param.ApplicationParam;
import cn.mw.cmdb.template.param.MwTemplateConfigurationParam;
import cn.mw.cmdb.template.strategy.TemplateDetailHandler;
import cn.mw.cmdb.template.utils.TemplateSortUtil;
import cn.mw.microMonitorCommon.constants.ZabbixApiConstants;
import cn.mw.microMonitorCommon.constants.ZabbixMethodConstants;
import cn.mw.microMonitorCommon.entity.common.MwTPServerTable;
import cn.mw.microMonitorCommon.entity.zabbix.MWZabbixAPIResult;
import cn.mw.microMonitorCommon.util.ListMapObjUtils;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @description 应用集处理
 */
@Service
@Slf4j
public class ApplicationHandler extends TemplateDetailHandler {


    private final String application = "Application";
    private final String itemId = "itemid";

    private final String ITEM_IDS = "itemids";
    private final String APPLICATION_IDS = "applicationids";
    private final String TAG = "tag";
    private final String VALUE = "value";

    @Override
    public TemplateDetailEnum handlerType() {
        return TemplateDetailEnum.APPLICATION;
    }


    @Override
    public Object getData(MwTemplateConfigurationParam param) {
        MwTPServerTable tpServerTable = tpServerService.getMwTPServerByServiceId(param.getServerId());
        if(tpServerTable == null){
            return null;
        }
        String monitoringServerVersion = tpServerTable.getMonitoringServerVersion();
        List<ApplicationDto> applicationDtos = new ArrayList<>();
        switch (monitoringServerVersion){
            case ZABBIX_V5:
                applicationDtos = zabbixV5GetApplication(param);
                break;
            default:
                applicationDtos = zabbixV6GetApplication(param);
        }
        if(CollectionUtils.isNotEmpty(applicationDtos) && StringUtils.isNotEmpty(param.getDetailName())){
            applicationDtos = applicationDtos.stream().filter(item->item.getApplicationName().contains(param.getDetailName())).collect(Collectors.toList());
        }
        //数据排序
        List realData = TemplateSortUtil.templateSortList(applicationDtos, param,param.getQuery());
        if(param.getPageNum() == null || param.getPageSize() == null){
            return realData;
        }
        Page page = pageHandler(realData, param.getPageNum(), param.getPageSize());
        return page;
    }

    @Override
    public Object createData(MwTemplateConfigurationParam param) {
        MwTPServerTable tpServerTable = tpServerService.getMwTPServerByServiceId(param.getServerId());
        if(tpServerTable == null){
            return null;
        }
        String monitoringServerVersion = tpServerTable.getMonitoringServerVersion();
        switch (monitoringServerVersion){
            case ZABBIX_V5:
                createZabbixV5Application(param);
                break;
            default:
                createZabbixV6Application(param);
        }
        return null;
    }

    @Override
    public Object updateData(MwTemplateConfigurationParam param) {
        MwTPServerTable tpServerTable = tpServerService.getMwTPServerByServiceId(param.getServerId());
        if(tpServerTable == null){
            return null;
        }
        String monitoringServerVersion = tpServerTable.getMonitoringServerVersion();
        switch (monitoringServerVersion){
            case ZABBIX_V5:
                updateZabbixV5Application(param);
                break;
            default:
                updateZabbixV6Application(param);
        }
        return null;
    }

    @Override
    public Object deleteData(MwTemplateConfigurationParam param) {
        MwTPServerTable tpServerTable = tpServerService.getMwTPServerByServiceId(param.getServerId());
        if(tpServerTable == null){
            return null;
        }
        String monitoringServerVersion = tpServerTable.getMonitoringServerVersion();
        switch (monitoringServerVersion){
            case ZABBIX_V5:
                deleteeZabbixV5Application(param);
                break;
            default:
                deleteZabbixV6Application(param);
        }
        return null;
    }

    @Override
    public Object selectDataById(MwTemplateConfigurationParam param) {
        return null;
    }

    private void deleteeZabbixV5Application(MwTemplateConfigurationParam param){
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.APPLICATION_DELETE, param.getDetailDeleteIds());
        if(zabbixAPIResult == null || zabbixAPIResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
    }

    private void deleteZabbixV6Application(MwTemplateConfigurationParam param){
        Object detailData = param.getDetailData();
        ApplicationParam applicationParam = JSONObject.parseObject(JSONObject.toJSONString(detailData), ApplicationParam.class);
        if(StringUtils.isEmpty(applicationParam.getApplicationName())){
            return;
        }
        //查询模板的标记
        Map zabbixTemplateParam = new HashMap();
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.TEMPLATE_IDS, param.getTemplateId());
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.OUTPUT, Arrays.asList(MwTemplateConfigurationConstant.TEMPLATE_ID));
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.selectTags, MwTemplateConfigurationConstant.EXTEND);
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TEMPLATE_GET, zabbixTemplateParam);
        if(zabbixAPIResult == null || zabbixAPIResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
        List<MwTemplateConvertOne> convertOnes = com.alibaba.fastjson.JSONArray.parseArray(String.valueOf(zabbixAPIResult.getData()), MwTemplateConvertOne.class);
        if(CollectionUtils.isEmpty(convertOnes)){return;}
        List<TagDto> tags = convertOnes.get(0).getTags();
        Iterator<TagDto> iterator = tags.iterator();
        while (iterator.hasNext()){
            TagDto next = iterator.next();
            if(next.getValue().equals(applicationParam.getApplicationName())){
                iterator.remove();
            }
        }
        List<Map> tagMaps = ListMapObjUtils.objectsToMaps(tags);
        //修改模板
        Map zabbixUpdateTemplateParam = new HashMap();
        zabbixUpdateTemplateParam.put(MwTemplateConfigurationConstant.TEMPLATE_ID,param.getTemplateId());
        zabbixUpdateTemplateParam.put(MwTemplateConfigurationConstant.TAGS,tagMaps);
        MWZabbixAPIResult zabbixUpdateTemplateResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TEMPLATE_UPDATE, zabbixUpdateTemplateParam);
        if(zabbixUpdateTemplateResult == null || zabbixUpdateTemplateResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixUpdateTemplateResult.getData()));
        }
    }

    private void updateZabbixV5Application(MwTemplateConfigurationParam param){
        Object detailData = param.getDetailData();
        ApplicationParam applicationParam = JSONObject.parseObject(JSONObject.toJSONString(detailData), ApplicationParam.class);
        if(StringUtils.isEmpty(applicationParam.getApplicationName()) || StringUtils.isEmpty(applicationParam.getApplicationId())){
            return;
        }
        Map zabbixApplicationParam = new HashMap();
        zabbixApplicationParam.put(applicationId,applicationParam.getApplicationId());
        zabbixApplicationParam.put(MwTemplateConfigurationConstant.NAME,applicationParam.getApplicationName());
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.APPLICATION_UPDATE, zabbixApplicationParam);
        if(zabbixAPIResult == null || zabbixAPIResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
    }

    private void updateZabbixV6Application(MwTemplateConfigurationParam param){
        Object detailData = param.getDetailData();
        ApplicationParam applicationParam = JSONObject.parseObject(JSONObject.toJSONString(detailData), ApplicationParam.class);
        if(StringUtils.isEmpty(applicationParam.getApplicationName())){
            return;
        }
        //查询模板的标记
        Map zabbixTemplateParam = new HashMap();
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.TEMPLATE_IDS, param.getTemplateId());
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.OUTPUT, Arrays.asList(MwTemplateConfigurationConstant.TEMPLATE_ID));
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.selectTags, MwTemplateConfigurationConstant.EXTEND);
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TEMPLATE_GET, zabbixTemplateParam);
        if(zabbixAPIResult == null || zabbixAPIResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
        List<MwTemplateConvertOne> convertOnes = com.alibaba.fastjson.JSONArray.parseArray(String.valueOf(zabbixAPIResult.getData()), MwTemplateConvertOne.class);
        if(CollectionUtils.isEmpty(convertOnes)){return;}
        List<TagDto> tags = convertOnes.get(0).getTags();
        for (TagDto tag : tags) {
            if(tag.getValue().equals(applicationParam.getApplicationOldName())){
                tag.setValue(applicationParam.getApplicationName());
            }
        }
        List<Map> tagMaps = ListMapObjUtils.objectsToMaps(tags);
        //修改模板
        Map zabbixUpdateTemplateParam = new HashMap();
        zabbixUpdateTemplateParam.put(MwTemplateConfigurationConstant.TEMPLATE_ID,param.getTemplateId());
        zabbixUpdateTemplateParam.put(MwTemplateConfigurationConstant.TAGS,tagMaps);
        MWZabbixAPIResult zabbixUpdateTemplateResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TEMPLATE_UPDATE, zabbixUpdateTemplateParam);
        if(zabbixUpdateTemplateResult == null || zabbixUpdateTemplateResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixUpdateTemplateResult.getData()));
        }
    }

    private void createZabbixV5Application(MwTemplateConfigurationParam param){
        Object detailData = param.getDetailData();
        ApplicationParam applicationParam = JSONObject.parseObject(JSONObject.toJSONString(detailData), ApplicationParam.class);
        if(StringUtils.isEmpty(applicationParam.getApplicationName())){
            return;
        }
        Map zabbixApplicationParam = new HashMap();
        zabbixApplicationParam.put(MwTemplateConfigurationConstant.HOST_ID,param.getTemplateId());
        zabbixApplicationParam.put(MwTemplateConfigurationConstant.NAME,applicationParam.getApplicationName());
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.APPLICATION_CREATE, zabbixApplicationParam);
        if(zabbixAPIResult == null || zabbixAPIResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
    }

    private void createZabbixV6Application(MwTemplateConfigurationParam param){
        Object detailData = param.getDetailData();
        ApplicationParam applicationParam = JSONObject.parseObject(JSONObject.toJSONString(detailData), ApplicationParam.class);
        if(StringUtils.isEmpty(applicationParam.getApplicationName())){
            return;
        }
        //查询模板的标记
        Map zabbixTemplateParam = new HashMap();
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.TEMPLATE_IDS, param.getTemplateId());
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.OUTPUT, Arrays.asList(MwTemplateConfigurationConstant.TEMPLATE_ID));
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.selectTags, MwTemplateConfigurationConstant.EXTEND);
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TEMPLATE_GET, zabbixTemplateParam);
        if(zabbixAPIResult == null || zabbixAPIResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
        List<MwTemplateConvertOne> convertOnes = com.alibaba.fastjson.JSONArray.parseArray(String.valueOf(zabbixAPIResult.getData()), MwTemplateConvertOne.class);
        if(CollectionUtils.isEmpty(convertOnes)){return;}
        List<TagDto> tags = convertOnes.get(0).getTags();
        TagDto tagDto = new TagDto();
        tagDto.setTag(application);
        tagDto.setValue(applicationParam.getApplicationName());
        if(tags == null){
            tags = new ArrayList<>();
        }
        tags.add(tagDto);
        List<Map> tagMaps = ListMapObjUtils.objectsToMaps(tags);
        //修改模板
        Map zabbixUpdateTemplateParam = new HashMap();
        zabbixUpdateTemplateParam.put(MwTemplateConfigurationConstant.TEMPLATE_ID,param.getTemplateId());
        zabbixUpdateTemplateParam.put(MwTemplateConfigurationConstant.TAGS,tagMaps);
        MWZabbixAPIResult zabbixUpdateTemplateResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TEMPLATE_UPDATE, zabbixUpdateTemplateParam);
        if(zabbixUpdateTemplateResult == null || zabbixUpdateTemplateResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixUpdateTemplateResult.getData()));
        }
    }

    private List<ApplicationDto> zabbixV5GetApplication(MwTemplateConfigurationParam param){
        List<ApplicationDto> applicationDtos = new ArrayList<>();
        //获取模板的应用集ID
        Map zabbixTemplateParam = new HashMap();
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.TEMPLATE_IDS,param.getTemplateId());
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.OUTPUT,MwTemplateConfigurationConstant.TEMPLATE_ID);
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.selectApplications, Arrays.asList(applicationId));
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TEMPLATE_GET, zabbixTemplateParam);
        if(zabbixAPIResult == null || zabbixAPIResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
        List<MwTemplateConvertOne> templateConvertOnes = JSONArray.parseArray(String.valueOf(zabbixAPIResult.getData()), MwTemplateConvertOne.class);
        if(CollectionUtils.isEmpty(templateConvertOnes)){
            return applicationDtos;
        }
        List<String> applicationIds = new ArrayList<>();
        for (MwTemplateConvertOne templateConvertOne : templateConvertOnes) {
            List<MwApplicationConvertDto> applications = templateConvertOne.getApplications();
            if(CollectionUtils.isEmpty(applications)){continue;}
            applicationIds.addAll(applications.stream().map(s->s.getApplicationid()).collect(Collectors.toList()));
        }
        if(CollectionUtils.isEmpty(applicationIds)){
            return applicationDtos;
        }
        Map zabbixApplicationParam = new HashMap();
        zabbixApplicationParam.put(MwTemplateConfigurationConstant.OUTPUT,Arrays.asList(MwTemplateConfigurationConstant.NAME,applicationId));
        zabbixApplicationParam.put(APPLICATION_IDS,applicationIds);
        zabbixApplicationParam.put(MwTemplateConfigurationConstant.selectItems,Arrays.asList(MwTemplateConfigurationConstant.ITEM_ID,MwTemplateConfigurationConstant.NAME));
        MWZabbixAPIResult applicationResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.APPLICATION_GET, zabbixApplicationParam);
        if(applicationResult == null || applicationResult.isFail()){
            throw new ZabbixResultException(String.valueOf(applicationResult.getData()));
        }
        List<MwApplicationConvertDto> applicationConvertDtos = JSONArray.parseArray(String.valueOf(applicationResult.getData()), MwApplicationConvertDto.class);
        if(CollectionUtils.isEmpty(applicationConvertDtos)){
            return applicationDtos;
        }
        for (MwApplicationConvertDto applicationConvertDto : applicationConvertDtos) {
            ApplicationDto applicationDto = new ApplicationDto();
            applicationDto.setApplicationId(applicationConvertDto.getApplicationid());
            applicationDto.setApplicationName(applicationConvertDto.getName());
            if(CollectionUtils.isNotEmpty(applicationConvertDto.getItems())){
                applicationDto.setMonitorItemCount(applicationConvertDto.getItems().size());
            }else{
                applicationDto.setMonitorItemCount(0);
            }
            applicationDtos.add(applicationDto);
        }
        return applicationDtos;
    }


    private List<ApplicationDto> zabbixV6GetApplication(MwTemplateConfigurationParam param){
        List<ApplicationDto> applicationDtos = new ArrayList<>();
        //先查询模板的监控项
        Map zabbixTemplateParam = new HashMap();
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.TEMPLATE_IDS,param.getTemplateId());
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.OUTPUT,MwTemplateConfigurationConstant.TEMPLATE_ID);
        zabbixTemplateParam.put(MwTemplateConfigurationConstant.selectItems, Arrays.asList(itemId));
        MWZabbixAPIResult zabbixAPIResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.TEMPLATE_GET, zabbixTemplateParam);
        if(zabbixAPIResult == null || zabbixAPIResult.isFail()){
            throw new ZabbixResultException(String.valueOf(zabbixAPIResult.getData()));
        }
        List<MwTemplateConvertOne> templateConvertOnes = JSONArray.parseArray(String.valueOf(zabbixAPIResult.getData()), MwTemplateConvertOne.class);
        if(CollectionUtils.isEmpty(templateConvertOnes)){
            return applicationDtos;
        }
        List<String> itemIds = new ArrayList<>();
        for (MwTemplateConvertOne templateConvertOne : templateConvertOnes) {
            List<MwMonitorItemConvertDto> items = templateConvertOne.getItems();
            if(CollectionUtils.isEmpty(items)){continue;}
            itemIds.addAll(items.stream().map(s->s.getItemid()).collect(Collectors.toList()));
        }
        if(CollectionUtils.isEmpty(itemIds)){
            return applicationDtos;
        }
        //查询item数据
        Map zabbixItemParam = new HashMap();
        zabbixItemParam.put(MwTemplateConfigurationConstant.OUTPUT,Arrays.asList(MwTemplateConfigurationConstant.ITEM_ID,MwTemplateConfigurationConstant.NAME));
        zabbixItemParam.put(ITEM_IDS,itemIds);
        zabbixItemParam.put(MwTemplateConfigurationConstant.selectTags,Arrays.asList(TAG,VALUE));
        MWZabbixAPIResult itemResult = zabbixDubboService.getZabbixApiResult(ZabbixApiConstants.GET_CUSTOM_INFO_BY_METHOD, param.getServerId(), ZabbixMethodConstants.ITEM_GET, zabbixItemParam);
        if(itemResult == null || itemResult.isFail()){
            throw new ZabbixResultException(String.valueOf(itemResult.getData()));
        }
        List<MwMonitorItemConvertDto> itemConvertDtos = JSONArray.parseArray(String.valueOf(itemResult.getData()), MwMonitorItemConvertDto.class);
        if(CollectionUtils.isEmpty(itemConvertDtos)){
            return applicationDtos;
        }
        Map<String,Integer> map = new HashMap<>();
        for (MwMonitorItemConvertDto itemConvertDto : itemConvertDtos) {
            List<MwMonitorTagConvertDto> tags = itemConvertDto.getTags();
            if(CollectionUtils.isEmpty(tags)){continue;}
            List<MwMonitorTagConvertDto> dtos = tags.stream().filter(item -> item.getTag().equals(application)).collect(Collectors.toList());
            for (MwMonitorTagConvertDto dto : dtos) {
                if(map.containsKey(dto.getValue())){
                    Integer count = map.get(dto.getValue());
                    map.put(dto.getValue(),count+1);
                }else{
                    map.put(dto.getValue(),1);
                }
            }
        }
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            String applicationName = entry.getKey();
            Integer count = entry.getValue();
            ApplicationDto applicationDto = new ApplicationDto();
            applicationDto.setApplicationName(applicationName);
            applicationDto.setMonitorItemCount(count);
            applicationDtos.add(applicationDto);
        }
        return applicationDtos;
    }
}
